package org.wk.account.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.wk.account.dao.SubAccountDao;
import org.wk.account.dao.yuan.SubAccountYuanAdminUpdateBillDao;
import org.wk.account.dao.yuan.SubAccountYuanDao;
import org.wk.account.dao.yuan.SubAccountYuanSeqDao;
import org.wk.account.domain.SubAccount;
import org.wk.account.domain.bao.SubAccountBaoAdminUpdateBill;
import org.wk.account.domain.bao.SubAccountBaoSeq;
import org.wk.account.domain.yuan.SubAccountYuan;
import org.wk.account.domain.yuan.SubAccountYuanAdminUpdateBill;
import org.wk.account.domain.yuan.SubAccountYuanSeq;
import org.wk.account.enums.AccountType;
import org.wk.account.enums.BaoChangeType;
import org.wk.account.enums.SeqFlag;
import org.wk.core.web.exception.GeneralException;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author TangShenShen
 * @Description: 鲸源变动实现类
 * @date 2018/5/189:45
 */
@Service
public class SubAccountYuanServiceImpl implements SubAccountYuanService {

    @Autowired
    private SubAccountYuanSeqDao subAccountYuanSeqDao;
    @Autowired
    private SubAccountYuanDao subAccountYuanDao;
    @Autowired
    private SubAccountDao subAccountDao;
    @Autowired
    private SubAccountYuanAdminUpdateBillDao subAccountYuanAdminUpdateBillDao;
    @Override
    public Page<SubAccountYuanSeq> findSeqByCriteria(Integer page, Integer size, SubAccountYuanSeq subAccountYuanSeq) {
        Sort sort = Sort.by(Sort.Direction.DESC,"createTime");
        Page<SubAccountYuanSeq> yuanSeqPage = subAccountYuanSeqDao.findAll(new Specification<SubAccountYuanSeq>() {
            @Override
            public Predicate toPredicate(Root<SubAccountYuanSeq> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

                List<Predicate> list = new ArrayList<Predicate>();
                if(null!=subAccountYuanSeq.getUserId()&&!"".equals(subAccountYuanSeq.getUserId())){
                    list.add(criteriaBuilder.equal(root.get("userId").as(String.class), subAccountYuanSeq.getUserId()));
                }
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            }
        }, PageRequest.of(page,size,sort));
        return yuanSeqPage;
    }

    @Override
    public void updateYuanAccount(BigDecimal yuan, String userId) {
        SubAccountYuan subAccountYuan = subAccountYuanDao.findByUserId(userId);
        SubAccountYuanSeq subAccountYuanSeq = new SubAccountYuanSeq();
        BigDecimal amount = subAccountYuan.getAmount();
        BigDecimal changeAmount = new BigDecimal(0);
        int num = yuan.compareTo(amount);
        if (num < 0){
            changeAmount = amount.subtract(yuan);
            subAccountYuanSeq.setSeqFlagCode(SeqFlag.EXPEND.getCode());
            subAccountYuanSeq.setSeqFlagName(SeqFlag.EXPEND.getName());
        }
        if (num > 0){
            changeAmount = yuan.subtract(amount);
            subAccountYuanSeq.setSeqFlagCode(SeqFlag.INCOME.getCode());
            subAccountYuanSeq.setSeqFlagName(SeqFlag.INCOME.getName());
        }
        if (num!=0 && yuan.compareTo(new BigDecimal(0))>=0){
            SubAccountYuanAdminUpdateBill adminUpdateBill = new SubAccountYuanAdminUpdateBill();
            adminUpdateBill.setAmount(changeAmount);
            adminUpdateBill.setUserId(userId);
            subAccountYuanAdminUpdateBillDao.save(adminUpdateBill);
            subAccountYuan.setAmount(yuan);
            subAccountYuan.setUserId(userId);
            subAccountYuanDao.saveOrUpdate(subAccountYuan);
            subAccountYuanSeq.setUserId(userId);
            subAccountYuanSeq.setChangeTypeCode(BaoChangeType.ADMIN_UPDATE.getCode());
            subAccountYuanSeq.setChangeTypeName(BaoChangeType.ADMIN_UPDATE.getName());
            subAccountYuanSeq.setPreAmount(amount);
            subAccountYuanSeq.setAmount(yuan);
            subAccountYuanSeq.setChangeAmount(changeAmount);
            subAccountYuanSeqDao.save(subAccountYuanSeq);
            SubAccount subAccount = subAccountDao.findByUserIdAndAccountTypeCode(userId, AccountType.JING_YUAN.getCode());
            subAccount.setAmount(yuan);
            subAccountDao.update(subAccount);
        }
    }

    @Override
    public Page<SubAccountYuanSeq> findSeqByUserIds(int pageNum, int pageSize, List<String> userIds) {
        Sort sort = Sort.by(Sort.Direction.DESC,"createTime");
        Page<SubAccountYuanSeq> zaiSeqPage = subAccountYuanSeqDao.findAll(new Specification<SubAccountYuanSeq>() {
            @Override
            public Predicate toPredicate(Root<SubAccountYuanSeq> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<Predicate>();
                if(!userIds.isEmpty()){
                    CriteriaBuilder.In<String> in = criteriaBuilder.in(root.get("userId"));
                    for (String userId:userIds){
                        in.value(userId);
                    }
                    list.add(in);
                }
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            }
        }, PageRequest.of(pageNum,pageSize,sort));
        return zaiSeqPage;
    }
}
